package com.welink.cmp.gatewayimpl.metadata;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.welink.cmp.convertor.FirewallConvertor;
import com.welink.cmp.convertor.GenericConvertor;
import com.welink.cmp.dao.metadata.FirewallDaoService;
import com.welink.cmp.dao.metadata.dataobject.FirewallDO;
import com.welink.cmp.domain.metadata.Firewall;
import com.welink.cmp.domain.metadata.gateway.IFirewallGateway;
import com.welink.cmp.dto.metadata.firewall.query.FirewallListByPageQry;
import com.welink.common.dto.PageResponse;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Marker;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Infra层 防火墙的Domain层 Gateway实现
 *
 * @author yanwei li create  2024-05-19 16:40
 */
@Component
@Primary
@Slf4j
public class FirewallGatewayImpl implements IFirewallGateway {

    @Autowired
    private FirewallDaoService daoService;



    /**
     * 创建或修改防火墙信息
     *
     * @param firewall 防火墙对象
     * @return 是否创建/修改成功
     */
    @Override
    @Transactional
    public boolean saveOrUpdateFirewall(Firewall firewall) {
        FirewallDO firewallDO = new FirewallDO();
        BeanUtils.copyProperties(firewall,firewallDO);
        boolean rst = daoService.saveOrUpdate(firewallDO);
        if (rst){
            // do firewall create event

        }
        return rst;
    }

    /**
     * 根据主键查询防火墙
     *
     * @param id 防火墙主键
     * @return 防火墙对象
     */
    @Override
    public Firewall getFirewallById(Long id) {
        Firewall firewall = new Firewall();
        FirewallDO firewallDO = daoService.getById(id);
        BeanUtils.copyProperties(firewallDO,firewall);
        return firewall;
    }

    /**
     * 分页查询防火墙信息
     */
    @Override
    public PageResponse<Firewall> pageQryFirewall(FirewallListByPageQry pageQry){
        int pageSize = pageQry.getPageSize();
        int pageIndex = pageQry.getPageIndex();

        Page<FirewallDO> rowPage = new Page<>(pageIndex,pageSize);
        LambdaQueryWrapper<FirewallDO> queryWrapper = Wrappers.lambdaQuery(FirewallDO.class);
        rowPage = daoService.page(rowPage, queryWrapper);

        PageResponse<Firewall> pageResponse = new PageResponse<>();
        pageResponse.setPageIndex((int)rowPage.getCurrent());
        pageResponse.setPageSize((int)rowPage.getSize());
        pageResponse.setData(FirewallConvertor.toDomainObjectList(rowPage.getRecords()));
        pageResponse.setTotalCount((int)rowPage.getTotal());

        return pageResponse;
    }

    /**
     * @param firewallList
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveOrUpdateBatchBySn(List<Firewall> firewallList) {

        final List<String> allSnList = firewallList.stream().map(Firewall::getSn).collect(Collectors.toList());
        LambdaQueryWrapper<FirewallDO> queryWrapper = Wrappers.lambdaQuery(FirewallDO.class);
        queryWrapper.select(FirewallDO::getSn).in(FirewallDO::getSn,allSnList);
        final List<FirewallDO> existFwList = daoService.list(queryWrapper);

        final Map<String, Long> existFwMap = existFwList.stream().collect(Collectors.toMap(FirewallDO::getSn, FirewallDO::getId));
        firewallList.forEach(firewall -> {
            final Long fwId = existFwMap.get(firewall.getSn());
            if ( fwId !=null){
                firewall.setId(fwId);
            }
        });
        List<FirewallDO> allFwDoList = GenericConvertor.toDOList(firewallList, FirewallDO.class);
        final boolean rst = daoService.saveOrUpdateBatch(allFwDoList);
        log.info("根据 Sn 批量更新或插入防火墙[{}]，更新Sn记录{},全部Sn{} ",rst,existFwList,allSnList);
        return null;
    }
}
